package middleware

import (
	"ginblog/config"
	errMsg "ginblog/model/err"
	"ginblog/model/response"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"strings"
	"time"
)

var JwtKey = []byte(config.JwtKey)

type MyClime struct {
	Username string
	jwt.StandardClaims
}

// 生成token
func SetToken(username string) (string, errMsg.Code) {
	expire := time.Now().Add(10 * time.Hour)
	SetClime := MyClime{
		username,
		jwt.StandardClaims{
			ExpiresAt: expire.Unix(),
			Issuer:    "ginblog",
		},
	}
	requestClimes := jwt.NewWithClaims(jwt.SigningMethodHS256, SetClime)
	token, err := requestClimes.SignedString(JwtKey)
	if err != nil {
		return "", errMsg.FAIL
	}
	return token, errMsg.SUCCESS
}

// 验证token
func CheckToken(token string) (*MyClime, errMsg.Code) {
	setToken, _ := jwt.ParseWithClaims(token, &MyClime{}, func(token *jwt.Token) (interface{}, error) {
		return JwtKey, nil
	})
	if key, ok := setToken.Claims.(*MyClime); ok && setToken.Valid {
		return key, errMsg.SUCCESS
	}
	return nil, errMsg.FAIL
}

// 中间件
func JWTToken() gin.HandlerFunc {
	return func(c *gin.Context) {
		tokenHerder := c.Request.Header.Get("Authorization")
		if tokenHerder == "" {
			response.Fail(c, errMsg.TOKEN_NOT_EXIST, nil)
			c.Abort()
			return
		}
		parts := strings.SplitN(tokenHerder, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			response.Fail(c, errMsg.TOKEN_TYPE_WRONG, nil)
			c.Abort()
		}
		mc, code := CheckToken(parts[1])
		if code != errMsg.SUCCESS {
			response.Fail(c, errMsg.TOKEN_WRONG, nil)
			c.Abort()
		}
		if time.Now().Unix() > mc.ExpiresAt {
			response.Fail(c, errMsg.TOKEN_EXPIRE, nil)
			c.Abort()
		}
		// 将当前请求的userID信息保存到请求的上下文c上
		c.Set("uid", mc.Username)
		c.Next()
	}
}
